package thread.synchroCode;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 交替打印123 ，无限循环
 *
 * 思路： 三个线程，一个标识位，三个线程分别负责打1/2/3
 * 对应标识位打印对应数字
 *
 */

@Slf4j(topic = "c.Test2405")
public class _05WaitNotify {
  static volatile int flag = 1;

  public static void main(String[] args) {
    ReentrantLock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();


    Thread t1 = new Thread(() -> {
      while (true){
        lock.lock();
        if (flag == 1){
          log.debug("1");
          flag = 2;
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          condition2.signalAll();
        } else {
          try {
            condition1.await();
            condition2.signalAll();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        lock.unlock();
      }
    });

    Thread t2 = new Thread(() -> {
      while (true) {
        lock.lock();
        if (flag == 2) {
          log.debug("2");
          flag = 3;
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          condition3.signalAll();
        } else {
          try {
            condition2.await();
            condition3.signalAll();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        lock.unlock();
      }
    });

    Thread t3 = new Thread(() -> {
      while (true) {
        lock.lock();
        if (flag == 3) {
          log.debug("3");
          flag = 1;
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          condition1.signalAll();
        } else {
          try {
            condition3.await();
            condition1.signalAll();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        lock.unlock();
      }
    });

    t1.start();
    t2.start();
    t3.start();
  }
}
